function initSearchResultPage() {
	$("#searchResultContent").parents("div:jqmData(role='page')").attr("id", "searchResultPage");
	
	$("script[type='text/x-jquery-tmpl']").each(function(index, item) {
		$.template($(item).attr("id"), $(item).html());
	});
	
	$("a[id$='PageNavButton']").on("click", function(event, ui) {
		handleNavButtonClick(event);
	});
	
	if ($("#tweetListDiv ul").length > 0) {
		$("#tweetListDiv ul").listview();
	}
	if ($("#userListDiv ul").length > 0) {
		$("#userListDiv ul").listview();
	}
	if ($("#tagListDiv ul").length > 0) {
		$("#tagListDiv ul").listview();
	}
	
	$("#tweetPageNavButton").trigger("click");
	var paginationControls = $("div[id$='PaginationControl']");
	$("ul li:first-child a", paginationControls).trigger("click");
	$("a:jqmData(index)", paginationControls).on("click", function(event, ui) {
		handleSearchResultPaginationButtonClick($(this));
	});
	
	$(".sortButton").on("click", function(event, ui) {
		handleSortButtonClick($(this));
	});
	
	$("#searchResultPage").on("pageshow", function() {
		var searchResultPage = $(this);
		
		var footer = searchResultPage.children("div:jqmData(role='footer')");
		var visiblePaginationControls = $("div[id$='PaginationControl']", footer);
		$.each(visiblePaginationControls, function(index, control) {
			var aControl = $(control);
			var currentItemPage = aControl.children("ul").attr("data-pagenumber");
			$("a:jqmData(index='" + currentItemPage + "')", aControl).addClass("ui-btn-active");
		});
		
		var visibleItemListId = visiblePaginationControls.filter(":visible").attr("data-for");
		var header = searchResultPage.children("div:jqmData(role='header')");
		$("a[href='#" + visibleItemListId + "']", header).addClass("ui-btn-active");
	});
	
	registerEntityNavHandler();
}

function handleNavButtonClick(event) {
	event.preventDefault();
	var pageToShow = $(event.currentTarget).attr("href").substring(1);
	$("div[id$='ListDiv']").each(function(index, item) {
		var anItem = $(item);
		if (anItem.attr("id") === pageToShow) {
			anItem.show();
		} else {
			anItem.hide();
		}
	});
	$("div[id$='PaginationControl']").each(function(index, item) {
		var anItem = $(item);
		if (anItem.attr("data-for") === pageToShow) {
			anItem.show();
		} else {
			anItem.hide();
		}
	});
	return false;
}

function registerEntityNavHandler() {
	$("div[id$='ListDiv'][id!='tweetListDiv'] ul li:not(:first-child) a").on("click", function(event, ui) {
		var clickedLink = $(this);
		
		var parentPage = clickedLink.parents("div:jqmData(role='page')"); 
		
		var entityId = clickedLink.attr("data-entityId");
		var entityListId = clickedLink.parents("div[id$='ListDiv']").attr("id");
		var entityType = $("div:jqmData(for='" + entityListId + "')[id$='PaginationControl'] ul", parentPage.children("div:jqmData(role='footer')")).attr("data-resultType");
		var entityName = $("div.column-1", clickedLink).text();
		
		handleEntityLinkClick(clickedLink, entityId, entityType, entityName);
	});
	
	$("#tweetListDiv span.mentionedUser, #tweetListDiv span.mentionedTag").on("click", function(event, ui) {
		var clickedLink = $(this);
		
		var entityId = clickedLink.attr("data-entityId");
		var entityType = clickedLink.attr("data-entityType");
		var entityName = clickedLink.text().substring(1);
		
		handleEntityLinkClick(clickedLink, entityId, entityType, entityName);
	});
	$("#tweetListDiv span.tweetOwner").on("click", function(event, ui) {
		var clickedLink = $(this);
		
		var entityId = clickedLink.attr("data-entityId");
		var entityType = clickedLink.attr("data-entityType");
		var entityName = clickedLink.text();
		
		handleEntityLinkClick(clickedLink, entityId, entityType, entityName);
	});
}

function prepareData(entityName, entityId, entityType, searchResult) {
	var data = new Object();
	data.entityName = entityName;
	data.entityId = entityId;
	data.entityType = entityType;
	data.interval = searchResult.interval;
	if (searchResult.tweets != null) {
		data.tweets = processTweets(searchResult.tweets);
		data.tweets.paginationControlData = preparePaginationControlData("tweetTabPaginationControl", "tweetTabListDiv", "tweets", searchResult.tweets);
	} else {
		data.tweets = null;
	}
	if (searchResult.users != null) {
		data.users = searchResult.users;
		data.users.paginationControlData = preparePaginationControlData("userTabPaginationControl", "userTabListDiv", "users", searchResult.users);
	} else {
		data.users = null;
	}
	if (searchResult.tags != null) {
		data.tags = searchResult.tags;
		data.tags.paginationControlData = preparePaginationControlData("tagTabPaginationControl", "tagTabListDiv", "tags", searchResult.tags);
	} else {
		data.tags = null;
	}
	return data;
}

function preparePaginationControlData(controlId, listId, resultType, paginatedSearchResult) {
	var maxPageToShow = 5;
	var startPage = 1;
	var endPage = paginatedSearchResult.totalPageNumber;
	var currentPage = paginatedSearchResult.pageNumber;
	
	var links = null;
	if (endPage <= maxPageToShow) {
		links = new Array();
		for (var i = startPage; i <= endPage; i++) {
			links.push(i);
		}
	} else {
		var nextPageOne, nextPageTwo, nextPageThree = -1;
		
		if (currentPage <= startPage + 2) {
			nextPageOne = startPage + 1;
			nextPageTwo = startPage + 2;
			nextPageThree = startPage + 3;
		} else if (currentPage >= endPage - 2) {
			nextPageOne = endPage - 3;
			nextPageTwo = endPage - 2;
			nextPageThree = endPage - 1;
		} else {
			nextPageOne = currentPage - 1;
			nextPageTwo = currentPage;
			nextPageThree = currentPage + 1;
		}
		links = [startPage, nextPageOne, nextPageTwo, nextPageThree, endPage];
	}

	return {
		controlId : controlId,
		listId : listId,
		resultType : resultType,
		sortBy : paginatedSearchResult.sortBy,
		sortOrder : paginatedSearchResult.sortOrder,
		pageSize : paginatedSearchResult.pageSize,
		pageNumber : paginatedSearchResult.pageNumber,
		totalPageNumber : paginatedSearchResult.totalPageNumber,
		links : links
	};
}

function handleTabButtonClick(event) {
	event.preventDefault();
	var pageToShow = $(event.currentTarget).attr("href").substring(1);
	$("div[id$='TabListDiv']").each(function(index, item) {
		var anItem = $(item);
		if (anItem.attr("id") === pageToShow) {
			anItem.show();
		} else {
			anItem.hide();
		}
	});
	$("div[id$='TabPaginationControl']").each(function(index, item) {
		var anItem = $(item);
		if (anItem.attr("data-for") === pageToShow) {
			anItem.show();
		} else {
			anItem.hide();
		}
	});
	return false;
}

function handleEntityLinkClick(linkElement, entityId, entityType, entityName, optionalPostParam) {
	var postData = createRelatedEntityPostData(linkElement, entityId, entityType);
	if (optionalPostParam) {
		$.extend(postData, optionalPostParam);
	}
	
	$.post(getContextPath() + "/doSearchRelatedEntities", postData, function(responseData) {
		var navPageContent = $.tmpl("entityNavDialogTemplate", prepareData(entityName, entityId, entityType, responseData.result));
		
		var navPage = $("<div id='entityNavPage' data-role='page'></div>");
		navPageContent.appendTo(navPage);
		navPage.appendTo("body");
		navPage.page();
		
		if ($("#tweetTabListDiv ul", navPageContent).length > 0) {
			$("#tweetTabListDiv ul", navPageContent).listview();
		}
		if ($("#userTabListDiv ul", navPageContent).length > 0) {
			$("#userTabListDiv ul", navPageContent).listview();
		}
		if ($("#tagTabListDiv ul", navPageContent).length > 0) {
			$("#tagTabListDiv ul", navPageContent).listview();
		}
		
		navPage.one("pagehide", function() {
			$(this).remove();
		});
		
		navPage.one("pageshow", function() {
			$("a[id$='TabButton']", navPageContent).on("click", function(event, ui) {
				handleTabButtonClick(event);
			});
			$("li:first-child a[id$='TabButton']", navPageContent).trigger("click");
			
			var paginationControls = $("div[id$='TabPaginationControl']", navPageContent);
			$("ul li:first-child a", paginationControls).trigger("click");
			$("a:jqmData(index)", paginationControls).on("click", function(event, ui) {
				handlePaginationEntityButtonClick($(this));
			});
			
			$(".sortButton", navPageContent).on("click", function(event, ui) {
				handleSortButtonClick($(this));
			});
			$(".backButton", navPageContent).on("click", function(event, ui) {
				$("#entityNavPage").one("pagehide", function () {
				    $(this).remove();
				});
				$.mobile.changePage("#searchResultPage");
			});
			$("div[id$='ListDiv'][id!='tweetTabListDiv'] ul li:not(:first-child) a", navPageContent).on("click", function(event, ui) {
				var clickedLink = $(this);
				
				var parentPage = clickedLink.parents("div:jqmData(role='page')"); 
				
				var entityId = clickedLink.attr("data-entityId");
				var entityListId = clickedLink.parents("div[id$='ListDiv']").attr("id");
				var entityType = $("div:jqmData(for='" + entityListId + "')[id$='PaginationControl'] ul", parentPage.children("div:jqmData(role='footer')")).attr("data-resultType");
				var entityName = $("div.column-1", clickedLink).text();
				
				handleEntityLinkClick(clickedLink, entityId, entityType, entityName);
			});
			$("#tweetTabListDiv span.mentionedUser, #tweetTabListDiv span.mentionedTag", navPageContent).on("click", function(event, ui) {
				var clickedLink = $(this);
				
				var entityId = clickedLink.attr("data-entityId");
				var entityType = clickedLink.attr("data-entityType");
				var entityName = clickedLink.text().substring(1);
				
				handleEntityLinkClick(clickedLink, entityId, entityType, entityName);
			});
			$("#tweetTabListDiv span.tweetOwner", navPageContent).on("click", function(event, ui) {
				var clickedLink = $(this);
				
				var entityId = clickedLink.attr("data-entityId");
				var entityType = clickedLink.attr("data-entityType");
				var entityName = clickedLink.text();
				
				handleEntityLinkClick(clickedLink, entityId, entityType, entityName);
			});
		});
		$.mobile.changePage(navPage, {allowSamePageTransition : true});
	});
}

function handleSearchResultPaginationButtonClick(linkElement) {
	var clickedLink = linkElement;
	
	var sortBy = clickedLink.parent().parent().attr("data-sortBy");
	var sortOrder = clickedLink.parent().parent().attr("data-sortOrder");
	var pageToLoad = clickedLink.attr("data-index");
	var entityType = clickedLink.parent().parent().attr("data-resultType");
	var intervalId = $("#searchResultFooter").attr("data-intervalId");
	var topicId = $("#searchResultFooter").attr("data-topicId");
	
	$.post(getContextPath() + "/doSearch", {topicId: topicId, intervalId: intervalId, entityType: entityType, pageNumber: pageToLoad, sortBy: sortBy, sortOrder: sortOrder}, function(responseData) {
		var searchResult = responseData.result[entityType];
		
		var itemListContainerId = clickedLink.parents("div[id$='PaginationControl']").attr("data-for");
		
		if (searchResult.total === 0) {
			var itemListContainer = $("#" + itemListContainerId);
			itemListContainer.empty();
			itemListContainer.append("No " + entityType + " found");
			
			var paginationList = clickedLink.parent().parent();
			paginationList.children().remove("li:not(:first-child)");
		} else {
			//refresh list
			var itemList = $("#" + itemListContainerId).find("ul");
			itemList.children().remove("li:not(:first-child)");
			var items = null;
			if (itemList.parent().attr("id") !== "tweetListDiv") {
				items = searchResult;
			} else {
				items = processTweets(searchResult);
			}
			$.each(items.items, function(index, item) {
				$.tmpl(entityType + "ItemTemplate", item).appendTo(itemList);
			});
			itemList.listview("refresh");
			if (itemList.parent().attr("id") === "tweetListDiv") {
				itemList.find("span.mentionedUser, span.mentionedTag").on("click", function(event, ui) {
					var clickedLink = $(this);
					
					var entityId = clickedLink.attr("data-entityId");
					var entityType = clickedLink.attr("data-entityType");
					var entityName = clickedLink.text().substring(1);
					
					handleEntityLinkClick(clickedLink, entityId, entityType, entityName);
				});
				itemList.find("span.tweetOwner").on("click", function(event, ui) {
					var clickedLink = $(this);
					
					var entityId = clickedLink.attr("data-entityId");
					var entityType = clickedLink.attr("data-entityType");
					var entityName = clickedLink.text();
					
					handleEntityLinkClick(clickedLink, entityId, entityType, entityName);
				});
			} else {
				itemList.find("li:not(:first-child) a").on("click", function(event, ui) {
					var clickedLink = $(this);
					
					var parentPage = clickedLink.parents("div:jqmData(role='page')"); 
					
					var entityId = clickedLink.attr("data-entityId");
					var entityListId = clickedLink.parents("div[id$='ListDiv']").attr("id");
					var entityType = $("div:jqmData(for='" + entityListId + "')[id$='PaginationControl'] ul", parentPage.children("div:jqmData(role='footer')")).attr("data-resultType");
					var entityName = $("div.column-1", clickedLink).text();
					
					handleEntityLinkClick(clickedLink, entityId, entityType, entityName);
				});
			}
			
			refreshListHeader(itemList, searchResult.sortBy, searchResult.sortOrder);
			
			refreshPaginationControl(clickedLink.parent().parent(), searchResult, handleSearchResultPaginationButtonClick);
		}
	});
}

function handlePaginationEntityButtonClick(linkElement) {
	var entityId = linkElement.parents("div:jqmData(role='page')").children("div:jqmData(role='header')").attr("data-entityId");
	var entityType = linkElement.parents("div:jqmData(role='page')").children("div:jqmData(role='header')").attr("data-entityType");
	var relatedEntityType = linkElement.parents("ul").attr("data-resultType");
	var sortBy = linkElement.parents("ul").attr("data-sortBy");
	var sortOrder = linkElement.parents("ul").attr("data-sortOrder");
	
	var postData = createRelatedEntityPostData(linkElement, entityId, entityType);
	var optionalPostData = {pageNumber: linkElement.attr("data-index"), relatedEntityType: relatedEntityType, sortBy: sortBy, sortOrder: sortOrder};
	$.extend(postData, optionalPostData);
	
	$.post(getContextPath() + "/doSearchRelatedEntity", postData, function(responseData) {
		var searchResult = responseData.result[relatedEntityType];
		
		var itemListContainerId = linkElement.parents("div[id$='TabPaginationControl']").attr("data-for");
		
		if (searchResult.total === 0) {
			var itemListContainer = $("#" + itemListContainerId);
			itemListContainer.empty();
			itemListContainer.append("No " + relatedEntityType + " found");
			
			var paginationList = linkElement.parent().parent();
			paginationList.children().remove("li:not(:first-child)");
		} else {
			//refresh list
			var itemList = $("#" + itemListContainerId).find("ul");
			itemList.children().remove("li:not(:first-child)");
			var items = null;
			if (itemList.parent().attr("id") !== "tweetTabListDiv") {
				items = searchResult;
			} else {
				items = processTweets(searchResult);
			}
			$.each(items.items, function(index, item) {
				$.tmpl(relatedEntityType + "ItemTemplate", item).appendTo(itemList);
			});
			itemList.listview("refresh");
			if (itemList.parent().attr("id") !== "tweetTabListDiv") {
				itemList.find("li:not(:first-child) a").on("click", function(event, ui) {
					var clickedLink = $(this);
					
					var parentPage = clickedLink.parents("div:jqmData(role='page')"); 
					
					var entityId = clickedLink.attr("data-entityId");
					var entityListId = clickedLink.parents("div[id$='ListDiv']").attr("id");
					var entityType = $("div:jqmData(for='" + entityListId + "')[id$='PaginationControl'] ul", parentPage.children("div:jqmData(role='footer')")).attr("data-resultType");
					var entityName = $("div.column-1", clickedLink).text();
					
					handleEntityLinkClick(clickedLink, entityId, entityType, entityName);
				});
			} else {
				itemList.find("span.mentionedUser, span.mentionedTag").on("click", function(event, ui) {
					var clickedLink = $(this);
					
					var entityId = clickedLink.attr("data-entityId");
					var entityType = clickedLink.attr("data-entityType");
					var entityName = clickedLink.text().substring(1);
					
					handleEntityLinkClick(clickedLink, entityId, entityType, entityName);
				});
				itemList.find("span.tweetOwner").on("click", function(event, ui) {
					var clickedLink = $(this);
					
					var entityId = clickedLink.attr("data-entityId");
					var entityType = clickedLink.attr("data-entityType");
					var entityName = clickedLink.text();
					
					handleEntityLinkClick(clickedLink, entityId, entityType, entityName);
				});
			}
			
			refreshListHeader(itemList, searchResult.sortBy, searchResult.sortOrder);
			
			refreshPaginationControl(linkElement.parent().parent(), searchResult, handlePaginationEntityButtonClick);
		}
	});
}

function handleSortButtonClick(sortButton) {
	var paginationControlId = sortButton.parents("li.listHeader").attr("data-controlId");
	var paginationControls = $("#" + paginationControlId).find("ul");
	
	var currentSortBy = paginationControls.attr("data-sortBy");
	var newSortBy = sortButton.attr("data-sortBy");
	if (newSortBy !== currentSortBy) {
		paginationControls.attr("data-sortBy", newSortBy);
		paginationControls.attr("data-sortOrder", "desc");
	} else {
		var currentSortOrder = paginationControls.attr("data-sortOrder");
		if (currentSortOrder === "desc") {
			paginationControls.attr("data-sortOrder", "asc");
		} else {
			paginationControls.attr("data-sortOrder", "desc");
		}
	}
	$("li:first-child a", paginationControls).trigger("click");
}

function createRelatedEntityPostData(linkElement, entityId, entityType) {
	var parentPage = linkElement.parents("div:jqmData(role='page')");
	var pageFooter = $("div:jqmData(role='footer')", parentPage);
	
	var topicId = pageFooter.attr("data-topicId");
	var intervalId = pageFooter.attr("data-intervalId");
	
	return {topicId: topicId, intervalId: intervalId, entityId: entityId, entityType: entityType};
}

function processTweets(tweets) {
	$.each(tweets.items, function(tweetIndex, tweet) {
		if (tweet.mentionedTags) { 
			$.each(tweet.mentionedTags, function(tagIndex, tag) {
				var wrappedLink = "<span class='mentionedTag' data-entityType='tags' data-entityId='" + tag.hashTag.id + "'>#" + tag.hashTag.text + "</span>";
				tweet.text = replaceAll(tweet.text, "#" + tag.hashTag.text, wrappedLink);
			});
		}
		if (tweet.mentionedUsers) {
			$.each(tweet.mentionedUsers, function(userIndex, user) {
				var wrappedLink = "<span class='mentionedUser' data-entityType='users' data-entityId='" + user.user.id + "'>@" + user.user.name + "</span>";
				tweet.text = replaceAll(tweet.text, "@" + user.user.name, wrappedLink);
			});
		}
		tweet.owner = "<span class='tweetOwner' data-entityType='users' data-entityId='" + tweet.ownerId + "'>" + tweet.owner + "</span>";
	});
	return tweets;
}

function refreshListHeader(list, sortBy, sortOrder) {
	var sortButtons = list.children().filter("li.listHeader").find("button.sortButton");
	$.each(sortButtons, function(index, item) {
		var button = $(item);
		
		if (button.attr("data-sortBy") === sortBy) {
			button.attr("data-iconpos", "right");
			if (sortOrder === "desc") {
				button.attr("data-icon", "arrow-d");
			} else {
				button.attr("data-icon", "arrow-u");
			}
		} else {
			button.removeAttr("data-iconpos");
			button.attr("data-icon", false);
		}
		button.buttonMarkup();
	});
}

function refreshPaginationControl(paginationControlList, paginatedResult, handler) {
	var container = paginationControlList.parent().parent();
	
	var paginationBarId = paginationControlList.parent().attr("id");
	var paginationBarDataFor = paginationControlList.parent().attr("data-for");
	var paginationControlResultType = paginationControlList.attr("data-resultType");
	
	paginationControlList.parent().detach();
	
	var paginationBar = $("<div data-role='navbar'></div>");
	paginationBar.attr("id", paginationBarId);
	paginationBar.attr("data-for", paginationBarDataFor);
	
	var paginationControls = $("<ul data-icon='false'></ul>");
	paginationControls.attr("data-resultType", paginationControlResultType);
	paginationControls.attr("data-pageSize", paginatedResult.pageSize);
	paginationControls.attr("data-pageNumber", paginatedResult.pageNumber);
	paginationControls.attr("data-totalPageNumber", paginatedResult.totalPageNumber);
	paginationControls.attr("data-sortBy", paginatedResult.sortBy);
	paginationControls.attr("data-sortOrder", paginatedResult.sortOrder);
	
	var maxPage = 5;
	var startPage = 1;
	var endPage = paginatedResult.totalPageNumber;
	var currentPage = paginatedResult.pageNumber;
	
	var links = new Array();
	if (endPage <= maxPage) {
		for (var i = startPage; i <= endPage; i++) {
			links.push(i);
		}
	} else {
		links.push(startPage);
		
		if (currentPage <= startPage + 2) {
			links.push(startPage + 1);
			links.push(startPage + 2);
			links.push(startPage + 3);
		} else if (currentPage >= endPage - 2) {
			links.push(endPage - 3);
			links.push(endPage - 2);
			links.push(endPage - 1);
		} else {
			links.push(currentPage - 1);
			links.push(currentPage);
			links.push(currentPage + 1);
		}
		
		links.push(endPage);
	}
	
	for (var i = 0; i < links.length; i++) {
		var button = $("<a data-role='button' data-index='" + links[i] + "'>" + links[i] + "</a>");
		button.on("click", function(event, ui) {
			handler.call(this, $(this));
		});
		
		var li = $("<li></li>");
		button.appendTo(li);
		
		li.appendTo(paginationControls);
	}
	paginationControls.appendTo(paginationBar);
	paginationBar.appendTo(container);
	paginationBar.navbar();
	
	for (var i = 1; i <= links.length; i++) {
		var button = $("li:nth-child(" + i + ")", paginationControls).find("a:jqmData(index)");
		if (i === currentPage) {
			button.addClass("ui-btn-active");
		} else {
			button.removeClass("ui-btn-active");
		}
	}
}